/*
 *
 *
 */

#ifndef ZLBASE_PROTOCOL_H_
#define ZLBASE_PROTOCOL_H_

#include <cstdint>
#include <memory>

#include "zlbase/datalink/IBaseDatalink.h"
#include "zlbase/global.h"
#include "zlbase/protocol/DeviceDefines.h"

namespace zl
{
namespace zlbase
{
/// \brief 协议类型定义
enum EProtocolType
{
    EProtocolType_DCB = ZLBASE_PROTOCOl(1000),  ///< 开门板协议类型
    EProtocolType_MCB = ZLBASE_PROTOCOl(2000),  ///< 控制板类型
    EProtocolType_TCB = ZLBASE_PROTOCOl(3000)   ///< 温控板类型
};

/// \brief 协议基类
class ZLBASE_API IProtocol
{
public:
    IProtocol();
    virtual ~IProtocol();

    /// \brief 注入链路依赖
    ///
    /// 当使用IDevice，用户不应主动调用该接口
    void SetDatalink(std::shared_ptr<IBaseDatalink> datalink);

    /// \brief 获取链路对象
    ///
    /// 当使用IDevice，用户不应主动调用该接口
    std::shared_ptr<IBaseDatalink> GetDatalink();

    /// \brief 设置控制板IP地址
    ///
    /// 设置指定控制板的MAC地址和IP地址（广播指令）,一个开门版只有一个ip和mac地址
    /// \param[in] col 指定的控制板板号
    /// \param[in] ip 指定控制板的IP地址
    /// \param[in] mac 指定控制板的MAC地址
    /// \return 错误码
    virtual int32_t SetAddressInfo(int32_t col, const char *ip, const char *mac);

    /// \brief 获取控制板MAC地址和IP地址
    ///
    /// 获取指定控制板的MAC地址和IP地址（广播指令）,一个开门版只有一个ip和mac地址
    /// \param[in] col 指定的控制板板号
    /// \param[out] ip 指定控制板的IP地址
    /// \param[out] mac 指定控制板的MAC地址
    /// \return 错误码
    virtual int32_t GetAddressInfo(int32_t col, char *ip, char *mac);

    /// \brief 设置控制板MAC地址
    ///
    /// 控制板预设置的新的MAC地址（单播指令）
    /// \param[in] col 指定的控制板板号
    /// \param[in] mac 指定控制板的MAC地址
    /// \return 错误码
    virtual int32_t SetMacAddress(int32_t col, const char *mac);

    /// \brief 获取控制板MAC地址
    ///
    /// 获取控制板MAC地址（单播指令）
    /// \param[in] col 指定的控制板板号
    /// \param[out] mac 指定控制板的MAC地址
    /// \return 错误码
    virtual int32_t GetMacAddress(int32_t col, char *mac);

    /// \brief 查询控制板软件版本号
    ///
    /// 该接口用于通过控制板复位开门板和工控机（单播指令），固件版本号示例：v1.0.1
    /// \param[in] col 指定控制板号
    /// \param[out] version 固件版本号
    /// \return 错误码
    virtual int32_t GetFirmwareVersion(int32_t col, char *version);

    /// \brief 数据驱动接口
    ///
    /// 该接口用于某些特殊设备的自定义接口
    /// \param [in] command 自定义的指令数据
    /// \param [in] command_len 自定义指令的长度
    /// \param [out] result 处理的结果数据
    /// \param [out] result 处理结果数据的长度
    /// \return 错误码
    virtual int32_t ExecCommand(const unsigned char *command, size_t command_len,
                                unsigned char *result, size_t &result_len);

private:
    class IProtocolPrivate;
    IProtocolPrivate *p_;
};

}  // namespace zlbase
}  // namespace zl

#endif  // ZLBASE_PROTOCOL_H_
